#include<iostream>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<vector>

typedef void (*handler_t)();//函数指针类型

std::vector<handler_t> handlers;//函数指针数组

void fun_one()
{
    printf("这是一个临时任务1\n");
}

void fun_two()
{
    printf("这是一个临时任务2\n");
}

//设置对应的方法回调
//以后想让父进程闲了执行任何方法时，只要向Load里面注册，就可以让父进程执行对应的方法！
void Load()
{
    handlers.push_back(fun_one);
    handlers.push_back(fun_two);
}

int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        //子进程
        int cnt = 5;
        while (cnt)
        {
            printf("我是子进程：%d\n",cnt--);
            sleep(1);
        }
        exit(11);//仅仅用来测试
    }
    else
    {
        int quit = 0;
        while (!quit)
        {
            int status = 0;
            pid_t res = waitpid(-1,&status,WNOHANG);//以非阻塞状态等待
            if (res > 0)
            {
                //等待成功&&子进程退出
                printf("等待子进程退出成功：退出码：%d\n",WEXITSTATUS(status));
                quit = 1;
            }
            else if (res == 0)
            {
                //等待成功 && 但子进程并未退出
                printf("子进程还在运行中，暂时还没有退出，父进程可以在等一等，处理一下其他事情？\n");
                if(handlers.empty()) 
                {
                    Load();
                }
                std::vector<handler_t>::iterator it = handlers.begin();
                while(it != handlers.end())
                {
                    //执行处理其他任务
                    (*it)();
                    ++it;
                }   
            }
            else
            {
                //等待失败
                printf("wait失败！\n");
                quit = 1;
            }
            sleep(1);
        }




       // //父进程
       // int status = 0;
       // //只有子进程退出时，父进程才会waitpid函数，进程返回，父进程依旧还活着！
       // //waitpid/wait 可以在目前情况下，让进程退出具有一定的顺序性！
       // //将来可以让父进程进程更多的收尾工作
       // //id > 0 : 等待指定进程
       // //id = -1 ：等待任意一个子进程退出，等价于wait()
       // //options:默认为0，代表阻塞等待，WNOHANG: 叫做非阻塞等待
       // pid_t result = waitpid(id, &status, 0);//默认在阻塞状态去等待子进程状态变化(就是退出)
       // if (result > 0)
       // {
       //     //可以不这么检测
       //     //printf("父进程等待成功，退出码：%d, 退出信号：%d\n", (status >> 8) & 0xFF, status & 0x7F);
       //     if(WIFEXITED(status))
       //     {
       //         //子进程是正常退出的
       //         printf("子进程执行完毕的退出码：%d\n", WEXITSTATUS(status));
       //     }
       //     else
       //     {
       //         printf("子进程异常退出：%d\n",WIFEXITED(status));
       //     }
       // }
    }

}
